﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;

namespace SharedLib.CrossCuttingFramework
{
    /// <summary>
    /// Provides a mapping between interface and its classes
    /// </summary>
    public class InterfaceOrganizer
    {
        private ICollection<Type> _registeredInterfaces = new Collection<Type>();
        /// <summary>
        /// Interfaces of the Registered Classes
        /// </summary>
        public ICollection<Type> RegisteredInterfaces
        {
            get { return _registeredInterfaces; }
        }

        private IDictionary<Type, IDictionary<string, Type>> _registeredClasses = new Dictionary<Type, IDictionary<string, Type>>();

        public IDictionary<Type, IDictionary<string, Type>> RegisteredClasses
        {
            get { return _registeredClasses; }
        }

        public void RegisterInterface<T>() where T : class
        {
            Type t = typeof(T);
            if (!RegisteredInterfaces.Contains(t)) RegisteredInterfaces.Add(t);
        }

        public void RegisterClass(Type typeClass, string name)
        {
            foreach (Type typeInterface in typeClass.GetInterfaces())
            {
                if (RegisteredInterfaces.Contains(typeInterface))
                {
                    IDictionary<string, Type> classesInSpecifiedInterface;
                    //string interfaceName = typeInterface.FullName;
                    if (!RegisteredClasses.ContainsKey(typeInterface))
                    {
                        classesInSpecifiedInterface = new Dictionary<string, Type>();
                        RegisteredClasses.Add(typeInterface, classesInSpecifiedInterface);
                    }
                    else
                    {
                        classesInSpecifiedInterface = RegisteredClasses[typeInterface];
                    }
                    classesInSpecifiedInterface.Add(name, typeClass);
                }
            }
        }

        public void RegisterClass(Type typeClass)
        {
            RegisterClass(typeClass, typeClass.FullName);
        }

        public void RegisterClass<T>(string name) where T : class
        {
            Type typeClass = typeof(T);
            RegisterClass(typeClass, name);
        }

        public void RegisterClass<T>() where T : class
        {
            Type typeClass = typeof(T);
            RegisterClass(typeClass, typeClass.FullName);
        }
    }
}
